package com.runchamp;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * Adaptes races to list
 */
public class JSONAdapterHistoryRacesList extends BaseAdapter {

    Context mContext;
    LayoutInflater mInflater;
    JSONArray mJsonArray;
    boolean mChooseRace;

    public JSONAdapterHistoryRacesList(Context context, LayoutInflater inflater) {
        mContext = context;
        mInflater = inflater;
        mJsonArray = new JSONArray();
    }

    @Override
    public int getCount() {
        return mJsonArray.length();
    }

    //////BaseAdapter functions///////

    @Override
    public Object getItem(int position) {
        return mJsonArray.optJSONObject(position);
    }

    @Override
    public long getItemId(int position) {
        JSONObject json = (JSONObject) getItem(position);
        try {
            long key = json.getLong("Key");
            return key;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        // check if the view already exists, if so, no need to inflate and findViewById again!
        if (convertView == null) {

            // Inflate the custom row layout from your XML.
            convertView = mInflater.inflate(R.layout.row_history_race, null);
            // create a new "Holder" with subviews
            holder = new ViewHolder();
            holder.distanceTextView = (TextView) convertView.findViewById(R.id.text_distance);
            holder.dateTextView = (TextView) convertView.findViewById(R.id.text_date);
            holder.gradeTextView = (TextView) convertView.findViewById(R.id.text_grade);
            holder.positionTextView = (TextView) convertView.findViewById(R.id.text_position);
            holder.timeTextView = (TextView) convertView.findViewById(R.id.text_time);
            // hang onto this holder for future recyclage
            convertView.setTag(holder);
        } else {
            // skip all the expensive inflation/findViewById and just get the holder you already made
            holder = (ViewHolder) convertView.getTag();
        }

        // Get the current race's data in JSON form
        JSONObject jsonObject = (JSONObject) getItem(position);

        // Grab the details from the JSON
        String distance = "";
        String date = "";
        String time = "";
        String rank = "";
        String grade = "";
        Date dateTime;

        if (jsonObject.has("Distance")) {
            distance = String.format("%.2f", jsonObject.optDouble("Distance"));
        }
        if (jsonObject.has("Time")) {
            time = jsonObject.optString("Time");
        }

        if (jsonObject.has("Grade")) {
            grade = jsonObject.optString("Grade");
        }

        if (jsonObject.has("Position")) {
            rank = jsonObject.optString("Position");
        }
        if (jsonObject.has("Date")) {
            String aStrTime = jsonObject.optString("Date");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                dateTime = sdf.parse(aStrTime);
            } catch (ParseException e) {
                dateTime = new Date();
                e.printStackTrace();
            }
            date = new SimpleDateFormat("dd.MM.yy").format(dateTime);

            Calendar raceDate = Calendar.getInstance();
            SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd");
            String raceDAteFormat = temp.format(dateTime);
            int raceYear = Integer.valueOf(raceDAteFormat.substring(0, 4));
            int raceMonth = Integer.valueOf(raceDAteFormat.substring(5, 7));
            raceMonth--; //january is 0 and not 1 as the text
            int raceDay = Integer.valueOf(raceDAteFormat.substring(8, 10));
            raceDate.set(Calendar.YEAR, raceYear);
            raceDate.set(Calendar.MONTH, raceMonth);
            raceDate.set(Calendar.DAY_OF_MONTH, raceDay);
            Calendar nowDate = Calendar.getInstance();
            //check if today
            if (raceDate.get(Calendar.YEAR) == nowDate.get(Calendar.YEAR)
                    && raceDate.get(Calendar.MONTH) == nowDate.get(Calendar.MONTH)
                    && raceDate.get(Calendar.DAY_OF_MONTH) == nowDate.get(Calendar.DAY_OF_MONTH)) {
                String day = "Today";
                date = day;
            }
            //check if yesterday date
            else {
                nowDate.add(Calendar.DATE, -1);
                if (raceDate.get(Calendar.YEAR) == nowDate.get(Calendar.YEAR)
                        && raceDate.get(Calendar.MONTH) == nowDate.get(Calendar.MONTH)
                        && raceDate.get(Calendar.DAY_OF_MONTH) == nowDate.get(Calendar.DAY_OF_MONTH)) {
                    String day = "Yesterday";
                    date = day;
                }
            }

        }

        // Send these Strings to the TextViews for display
        holder.distanceTextView.setText(distance);
        holder.timeTextView.setText(time);
        holder.positionTextView.setText(rank);
        holder.gradeTextView.setText(grade);
        holder.dateTextView.setText(date);


        return convertView;
    }

    public void updateData(JSONArray jsonArray) {
        // update the adapter's dataset
        mJsonArray = jsonArray;
        notifyDataSetChanged();
    }

    //////Update///////

    public void sortByDistance() {
        List<JSONObject> jsons = new ArrayList<JSONObject>();
        for (int i = 0; i < getCount(); i++) {
            jsons.add((JSONObject) getItem(i));
        }
        Collections.sort(jsons, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject a, JSONObject b) {
                double aDist = (a.has("Distance")) ? a.optDouble("Distance") : 0;
                double bDist = (b.has("Distance")) ? b.optDouble("Distance") : 0;
                return Double.compare(aDist, bDist);
            }
        });
        updateData(new JSONArray(jsons));
    }

    //////Sort functions///////

    public void sortByGrade() {
        List<JSONObject> jsons = new ArrayList<JSONObject>();
        for (int i = 0; i < getCount(); i++) {
            jsons.add((JSONObject) getItem(i));
        }
        Collections.sort(jsons, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject a, JSONObject b) {
                int aGrade = (a.has("Grade")) ? a.optInt("Grade") : 0;
                int bGrade = (b.has("Grade")) ? b.optInt("Grade") : 0;
                return Integer.compare(bGrade, aGrade);
            }
        });
        updateData(new JSONArray(jsons));
    }

    public void sortByPosition() {
        List<JSONObject> jsons = new ArrayList<JSONObject>();
        for (int i = 0; i < getCount(); i++) {
            jsons.add((JSONObject) getItem(i));
        }
        Collections.sort(jsons, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject a, JSONObject b) {
                int aPosition = (a.has("Position")) ? a.optInt("Position") : 0;
                int bPosition = (b.has("Position")) ? b.optInt("Position") : 0;
                return Integer.compare(bPosition, aPosition);
            }
        });
        updateData(new JSONArray(jsons));
    }

    public void sortByTime() {
        List<JSONObject> jsons = new ArrayList<JSONObject>();
        for (int i = 0; i < getCount(); i++) {
            jsons.add((JSONObject) getItem(i));
        }
        Collections.sort(jsons, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject a, JSONObject b) {
                Date aTime, bTime;

                if (a.has("Time")) {
                    String aStrTime = a.optString("Time");
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                    try {
                        aTime = sdf.parse(aStrTime);
                    } catch (ParseException e) {
                        aTime = new Date();
                        e.printStackTrace();
                    }
                } else
                    aTime = new Date();

                if (b.has("Time")) {
                    String aStrTime = b.optString("Time");
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                    try {
                        bTime = sdf.parse(aStrTime);
                    } catch (ParseException e) {
                        bTime = new Date();
                        e.printStackTrace();
                    }
                } else
                    bTime = new Date();

                return aTime.compareTo(bTime);
            }
        });
        updateData(new JSONArray(jsons));
    }

    private static class ViewHolder {
        public TextView distanceTextView;
        public TextView positionTextView;
        public TextView dateTextView;
        public TextView timeTextView;
        public TextView gradeTextView;
    }
}
